#ifndef __fullmetalVector_hpp
#include <cstring>

/* Vector class is used for dynamic memory management
This is more efficent than the std::vector<> class, because
objects are only created *once*, and are only destroyed, *once*
And also uses pointers rather than references, which simplifies
the process significantly. The object doesn't need to be a class,
because it only has one member, everything else is a member-function.
It also uses a C-string style of notating the end of the array.
The C++ 'delete' method is also used for each element, to ensure an
objects destructor *is* called.
Count -- Returns the number of elements
operator [x] -- return element x
push(<new T>) -- adds a new T to the array
pop() -- deletes the last element
swap(x,y) -- re-orders the list
(C) Full Metal - 2011.
Do not steal, or take credit for this work.
Leave this comment in this file.
*/

namespace fullMetal{
	template <class T>
	class Vector {
		private:
			T** tElements;
			unsigned int bufferSize,arraySize,allocatedMemory;
			/* bufferSize - Number of elements to buffer for.
			   arraySize - Number of elements initialized.
			   allocatedMemory - Number of element slots currently allocated */
			void allocate(unsigned int number){
				if(arraySize+number<=allocatedMemory) return;
				allocatedMemory += number;
				T** ntElements = new T*[allocatedMemory + number];
				memcpy(ntElements,tElements,arraySize * sizeof(T*));
				delete tElements;
				tElements = ntElements;
				return;
			}
			unsigned char validID(unsigned int ID){
				return (ID > arraySize);
			}
		public:
			Vector(unsigned int BS = 5):bufferSize(bs),arraySize(0),allocatedMemory(0){
				tElements = NULL;
			}
			~Vector(){
				T* ptr = tElements;
				for(unsigned int i = 0;i<arraySize;i++,ptr++) delete ptr;
				delete tElements;
			}
			void Add(T* nt = new T()){
				allocate(1);
				tElements[arraySize++] = nt;
			}
			void Add(T& nt){
				allocate(1);
				T* nt = (T*)new char[sizeof(T)];
				memcpy(nt,&nt,sizeof(T));
			}
			void Remove(unsigned int at = 0,unsigned int size = 1){
				if(!at)	delete [--arraySize];
				else{
					if(!validID(at+size)) return;
					--at;
					unsigned int oS = size;
					while(size--) delete tElements[at+size-1];
					memcpy(&(tElements[at]),&tElements[at+oS],arraySize- ((at + 1)+size) );
					arraySize -= oS;
				}
			}
			T& operator[](unsigned int ID){
				return *(tElements[--ID]);
			}

	};

}
#define __fullmetalVector_hpp
#endif
